package com.kellycheung.chicken_go_go;

import java.util.ArrayList;

import android.graphics.Matrix;

import com.kellycheung.chicken_go_go.BaseObject.GOAnchor;
import com.kellycheung.chicken_go_go.Chicken.ChickenStatus;
import com.kellycheung.chicken_go_go.GMediaPlayer.GMPType;
import com.kellycheung.chicken_go_go.GameScene.GameSceneStatus;

public class GOObstacleHandler {
	public class GOObstacle {
		protected GOObstacleHandler goohandler;
		protected GPosition gp;
		
		protected GameObject go;
		
		protected boolean bAppeared;
		protected boolean bInTheScene;
		protected ChickenStatus csCollidStatus;
		
		public GOObstacle( GOObstacleHandler p_goohandler , GameObject p_go , GPosition p_gp , ChickenStatus p_cs ) {
			try {
				this.goohandler = p_goohandler;
				this.go = p_go;
				this.bAppeared = false;
				this.bInTheScene = false;
				this.csCollidStatus = p_cs;
				
				if ( this.go != null && p_gp != null ) {
					this.gp = new GPosition( p_gp );
					this.gp.gcThis.set( this.go.gcCoord );
				}
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GOObstacle" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void destroy() {
			try {
				if ( this.go != null ) {
					this.go.destroy();
					this.go = null;
				}
				
				this.goohandler = null;
				this.gp = null;
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GOObstacle.destroy" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void setCoord( float p_fX , float p_fY ) {
			try {
				this.setCoord( new GCoordinate( p_fX , p_fY ) );
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GOObstacle.setCoord(float)" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void setCoord( GCoordinate p_gc ) {
			try {
				if ( this.go != null ) {
					this.go.setCoord( p_gc );
				}
				
				if ( this.gp != null ) {
					this.gp.gcThis.set( p_gc );
				}
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GOObstacle.setCoord(GCoordinate)" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void preGameLoopLogic() {
			try {
				this.bInTheScene = this.goohandler.grScene.grDrawScene.isCollided( this.go.grBound );
				
				if ( this.bAppeared ) {
					if ( !this.bInTheScene ) {
						this.goohandler.alboToBeRemove.add( this );
					}
					else if ( this.gp != null ) {
						this.gp.toNewPoint();
						this.setCoord( this.gp.gcThis );
					}
				}
				else {
					if ( this.bInTheScene ) {
						this.bAppeared = true;
						if ( this.gp != null ) {
							this.gp.toNewPoint();
							this.setCoord( this.gp.gcThis );
						}
					}
				}
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GOObstacle.preGameLoopLogic" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void gameLoopLogic() {
			try {
				if ( this.goohandler.grScene.chicken.isCollided( this.go.grBound ) ) {
					switch ( this.csCollidStatus ) {
					case collided:
						this.goohandler.grScene.coJumpBtn.release();
						this.goohandler.grScene.coRunBtn.release();
						this.goohandler.grScene.chicken.csStatus = ChickenStatus.collided; 
						this.goohandler.grScene.geMain.gmpPlayer.playMusic( GMPType.soundEffect , R.raw.hurt );
						this.goohandler.alboToBeRemove.add( this );
						break;
					case getCoin:
						this.goohandler.grScene.iCoins++;
						this.goohandler.alboToBeRemove.add( this );
						break;
					default:
						break;
					}
				}
			} catch ( Exception p_e ) {
				// TODO Auto-generated catch block
				GameUtil.LogMsg( this , "GOObstacle.gameLoopLogic" );
				GameUtil.ErrorHandler( this , p_e );
			}
		}
		
		public void postGameLoopLogic() {
		}
		
	}
	
	protected GameRacing grScene;
	
	protected ArrayList<GOObstacle> algoObstcale;
	protected ArrayList<GOObstacle> alboToBeRemove;
	
	protected GameSceneStatus gssAllowStatus;
	
	public GOObstacleHandler( GameRacing p_gr , GameSceneStatus p_gss ) {
		try {
			this.grScene = p_gr;
			this.gssAllowStatus = p_gss;
			
			this.algoObstcale = new ArrayList<GOObstacle>();
			this.alboToBeRemove = new ArrayList<GOObstacle>();
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void destroy() {
		try {
			if ( this.algoObstcale != null ) {
				for ( GOObstacle goo : this.algoObstcale ) {
					goo.destroy();
				}
				this.algoObstcale.clear();
				this.algoObstcale = null;
			}
			
			if ( this.alboToBeRemove != null ) {
				for ( GOObstacle goo : this.alboToBeRemove ) {
					goo.destroy();
				}
				this.alboToBeRemove.clear();
				this.alboToBeRemove = null;
			}
			
			this.grScene = null;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.destroy" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX ) {
		try {
			this.addObstacle( p_iImg , p_fX , this.grScene.fGroundLv , null , null , ChickenStatus.collided );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , ChickenStatus p_cs ) {
		try {
			this.addObstacle( p_iImg , p_fX , this.grScene.fGroundLv , null , null , p_cs );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , Matrix p_mRotator ) {
		try {
			this.addObstacle( p_iImg , p_fX , this.grScene.fGroundLv , p_mRotator , null , ChickenStatus.collided );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,Matrix)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , Matrix p_mRotator , ChickenStatus p_cs ) {
		try {
			this.addObstacle( p_iImg , p_fX , this.grScene.fGroundLv , p_mRotator , null , p_cs );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,Matrix,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , GPosition p_gp ) {
		try {
			this.addObstacle( p_iImg , p_fX , this.grScene.fGroundLv , null , p_gp , ChickenStatus.collided );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,GPosition)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , GPosition p_gp , ChickenStatus p_cs ) {
		try {
			this.addObstacle( p_iImg , p_fX , this.grScene.fGroundLv , null , p_gp , p_cs );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,GPosition,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , Matrix p_mRotator , GPosition p_gp ) {
		try {
			this.addObstacle( p_iImg , p_fX , this.grScene.fGroundLv , p_mRotator , p_gp , ChickenStatus.collided );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,Matrix,GPosition)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , Matrix p_mRotator , GPosition p_gp , ChickenStatus p_cs ) {
		try {
			this.addObstacle( p_iImg , p_fX , this.grScene.fGroundLv , p_mRotator , p_gp , p_cs );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,Matrix,GPosition,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , float p_fY ) {
		try {
			this.addObstacle( p_iImg , p_fX , p_fY , null , null , ChickenStatus.collided );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,float)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , float p_fY , ChickenStatus p_cs ) {
		try {
			this.addObstacle( p_iImg , p_fX , p_fY , null , null , p_cs );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,float,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , float p_fY , Matrix p_mRotator ) {
		try {
			this.addObstacle( p_iImg , p_fX , p_fY , p_mRotator , null , ChickenStatus.collided );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,float,Matrix)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , float p_fY , Matrix p_mRotator , ChickenStatus p_cs ) {
		try {
			this.addObstacle( p_iImg , p_fX , p_fY , p_mRotator , null , p_cs );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,float,Matrix,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , float p_fY , GPosition p_gp ) {
		try {
			this.addObstacle( p_iImg , p_fX , p_fY , null , p_gp , ChickenStatus.collided );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,float,GPosition)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , float p_fY , GPosition p_gp , ChickenStatus p_cs ) {
		try {
			this.addObstacle( p_iImg , p_fX , p_fY , null , p_gp , p_cs );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,float,GPosition,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( int[] p_iImg , float p_fX , float p_fY , Matrix p_mRotator , GPosition p_gp ) {
		try {
			this.addObstacle( p_iImg , p_fX , p_fY , p_mRotator , p_gp , ChickenStatus.collided );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,float,Matrix,GPosition)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	public void addObstacle( int[] p_iImg , float p_fX , float p_fY , Matrix p_mRotator , GPosition p_gp , ChickenStatus p_cs ) {
		try {
			GameObject goObs = new GameObject( this.grScene , -10 , GOAnchor.Down , p_fX , p_fY );
			if ( p_iImg[0] == R.drawable.ball ) {
				goObs.sObjName = "Ball";
			}
			
			goObs.addAnimation( p_iImg , p_mRotator );
			this.addObstacle( goObs , p_gp , p_cs );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(int[],float,float,Matrix,GPosition,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( GameObject p_go , ChickenStatus p_cs ) {
		try {
			this.addObstacle( p_go , null , p_cs );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(GameObject,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void addObstacle( GameObject p_go , GPosition p_gp , ChickenStatus p_cs ) {
		try {
			p_go.gssAllowStatus = this.gssAllowStatus;
			
			this.algoObstcale.add( new GOObstacle( this , p_go , p_gp , p_cs ) );
			
			this.grScene.addSceneObj( p_go );
			
			if ( p_go instanceof ClickableObj ) {
				this.grScene.addClickableObj( (ClickableObj)p_go );
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.addObstacle(GameObject,GPosition,ChickenStatus)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void setX( float p_fX ) {
		try {
			for ( GOObstacle goo : this.algoObstcale ) {
				if ( goo != null && goo.go != null ) {
					goo.setCoord( goo.go.gcCoord.fX - p_fX , goo.go.gcCoord.fY );
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.setX" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void preGameLoopLogic() {
		try {
			for ( GOObstacle goo : this.algoObstcale ) {
				if ( goo != null ) {
					goo.preGameLoopLogic();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.preGameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void gameLoopLogic() {
		try {
			for ( GOObstacle goo : this.algoObstcale ) {
				if ( goo != null ) {
					goo.gameLoopLogic();
				}
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.gameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void postGameLoopLogic() {
		try {
			for ( GOObstacle goo : this.algoObstcale ) {
				if ( goo != null ) {
					goo.postGameLoopLogic();
				}
			}
			
			for ( GOObstacle goo : this.alboToBeRemove ) {
				if ( goo != null ) {
					this.algoObstcale.remove( goo );
					
					if ( goo.go != null ) {
						this.grScene.removeSceneObj( goo.go );
					}
					
					goo.destroy();
				}
			}
			
			this.alboToBeRemove.clear();
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GOObstacleHandler.postGameLoopLogic" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
}
